package cn.springcloud.fix.gateway.filter;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.nio.CharBuffer;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.atomic.AtomicReference;

/**
 * 验证码处理
 */
@Slf4j
@Component
@AllArgsConstructor
public class ImgCodeFilter extends AbstractGatewayFilterFactory {

    private final static String OAUTH_TOKEN_URL = "/oauth/token";

    private final StringRedisTemplate redisTemplate;

    @Override
    public GatewayFilter apply(Object config) {
        return (exchange, chain) -> {
            try {
                /*ServerHttpRequest request = exchange.getRequest();

                // 不是登录请求，直接向下执行
                if (!StrUtil.containsAnyIgnoreCase(request.getURI().getPath(), OAUTH_TOKEN_URL)) {
                    return chain.filter(exchange);
                }

                // 刷新token，直接向下执行
                String grantType = request.getQueryParams().getFirst("grant_type");
                if (StrUtil.equals(SecurityConstant.REFRESH_TOKEN, grantType)) {
                    return chain.filter(exchange);
                }

                // 终端设置不校验， 直接向下执行
                String[] clientInfos = WebUtil.getClientId(request);
                if (filterIgnoreProperties.getClients().contains(clientInfos[0])) {
                    return chain.filter(exchange);
                }
                // 校验验证码
                // String bodyStr = resolveBodyFromRequest(request);
                // JSONObject bodyJson = JSONObject.parseObject(bodyStr);
                // String code = (String) bodyJson.get("captcha");
                // String randomStr = (String) bodyJson.get("randomStr");
                checkCode(request);*/
            } catch (Exception e) {
               /* ServerHttpResponse response = exchange.getResponse();
                response.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
                response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
                String msg = JSON.toJSONString(R.ERROR(e.getMessage()));
                DataBuffer bodyDataBuffer = response.bufferFactory().wrap(msg.getBytes());
                return response.writeWith(Mono.just(bodyDataBuffer));*/
            }

            return chain.filter(exchange);
        };
    }

    private String resolveBodyFromRequest(ServerHttpRequest serverHttpRequest) {
        Flux<DataBuffer> body = serverHttpRequest.getBody();
        AtomicReference<String> bodyRef = new AtomicReference<>();
        body.subscribe(buffer -> {
            CharBuffer charBuffer = StandardCharsets.UTF_8.decode(buffer.asByteBuffer());
            DataBufferUtils.release(buffer);
            bodyRef.set(charBuffer.toString());
        });
        return bodyRef.get();
    }

    /**
     * 检查code
     */
   /* private void checkCode(ServerHttpRequest request) throws ValidateCodeException {
        String code = request.getQueryParams().getFirst("code");

        if (StrUtil.isBlank(code)) {
            throw new ValidateCodeException("验证码不能为空");
        }

        String randomStr = request.getQueryParams().getFirst("randomStr");
        if (StrUtil.isBlank(randomStr)) {
            randomStr = request.getQueryParams().getFirst("mobile");
        }

        String key = CommonConstant.DEFAULT_CODE_KEY + randomStr;
        Object codeObj = redisTemplate.opsForValue().get(key);
        if (codeObj == null) {
            throw new ValidateCodeException("验证码不合法");
        }

        String saveCode = codeObj.toString();
        if (StrUtil.isBlank(saveCode)) {
            redisTemplate.delete(key);
            throw new ValidateCodeException("验证码不合法");
        }

        if (!StrUtil.equals(saveCode, code)) {
            redisTemplate.delete(key);
            throw new ValidateCodeException("验证码不合法");
        }

        redisTemplate.delete(key);
    }*/

    /**
     * 检查code
     */
   /* private void checkCode(String code, String randomStr) throws ValidateCodeException {
        if (StrUtil.isBlank(code)) {
            throw new ValidateCodeException("验证码不能为空");
        }
        if (StrUtil.isBlank(randomStr)) {
            throw new ValidateCodeException("验证码不合法");
        }
        String key = "random_code_" + randomStr;
        String saveCode = redisTemplate.opsForValue().get(key);
        redisTemplate.delete(key);
        if (!code.equalsIgnoreCase(saveCode)) {
            throw new ValidateCodeException("验证码不合法");
        }
    }*/
}
